import Draw from 'ol/interaction/Draw';
import WKT from 'ol/format/WKT';
import {
  createBox
} from 'ol/interaction/Draw';
import {
  getArea,
  getLength
} from 'ol/sphere.js';
import {
  LineString,
  Polygon
} from 'ol/geom.js';
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Icon,
  Style
} from 'ol/style.js';
import {
  Vector as VectorLayer
} from 'ol/layer';
import {
  XYZ,
  Vector
} from 'ol/source';

import {
  polygon as turfpolygon,
  circle as turfcircle,
  multiPolygon as turfmultipolygon,
  lineString as turflinestring,
  multiLineString as turfmultilinestring,
  point as turfpoint,
  centroid as turfcentroid,
  distance as turfdistance,
  toWgs84,
  area as turfarea,
  booleanIntersects
} from '@turf/turf';


import * as olProj from 'ol/proj';

import Feature from 'ol/Feature';

class cuiteFilter {
  constructor(map, layer) {
    this.map = map;
    if (!layer) {
      layer = new VectorLayer({
        source: new Vector({
          features: [],
          wrapX: false
        }),
        style: new Style({
          fill: new Fill({
            color: 'rgba(9,132,217, 0.2)'
          }),
          stroke: new Stroke({
            color: '#09EFED',
            width: 2
          }),
          image: new CircleStyle({
            radius: 3,
            fill: new Fill({
              color: '#09EFED'
            })
          })
        })
      })
      this.map.addLayer(layer);
    }
    this.layer = layer;
    this.format = new WKT();
    this.layer.setZIndex(9980);
    this.draw = null;
  }
  activateFilter(targetlayer, type, callback, errorback) {
    this.clearFilter();
    if (type == 'RectAngle') {
      var geometryFunction = createBox();
      this.draw = new Draw({
        source: this.layer.getSource(),
        type: 'Circle',
        geometryFunction: geometryFunction,
        style: new Style({
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          }),
          stroke: new Stroke({
            color: '#0098FD',
            width: 3
          }),
          image: new Icon({
            scale: 0.5,
            anchor: [0.5, 0.5],
            anchorXUnits: 'fraction',
            anchorYUnits: 'fraction',
            src: require('../../assets/images/cursor.png')
          })
        })
      });
    } else {
      this.draw = new Draw({
        source: this.layer.getSource(),
        type: type,
        style: new Style({
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          }),
          stroke: new Stroke({
            color: '#0098FD',
            width: 3
          }),
          image: new Icon({
            scale: 0.5,
            anchor: [0.5, 0.5],
            anchorXUnits: 'fraction',
            anchorYUnits: 'fraction',
            src: require('../../assets/images/cursor.png')
          })
        })
      });
    }

    this.map.addInteraction(this.draw);
    // this.map.interaction.click.setActive(false);
    // this.map.fixedMap(false);
    this.draw.on('drawend', (target) => {
      this.map.removeInteraction(this.draw);
      // this.map.fixedMap(true);
      setTimeout(() => {
        // this.map.interaction.click.setActive(true);
      }, 1000)
      this.draw = null;
      let wkt = '';
      let extent=target.feature.getGeometry().getExtent();
      if (type == 'Circle') {
        let geometry = new Polygon(this.createCircle(target.feature));
        wkt = this.format.writeGeometry(geometry, {
          dataProjection: 'EPSG:4326',
          featureProjection: 'EPSG:3857'
        });
      } else {
        wkt = this.format.writeFeature(target.feature, {
          dataProjection: 'EPSG:4326',
          featureProjection: 'EPSG:3857'
        });
      }
      let area = this.areaGeometry(wkt);
      // if(area>100000000 && errorback){
      // 	setTimeout(()=>{
      // 		this.clearFilter();
      // 	},250);
      // 	errorback();
      // 	return;
      // }

      let features = targetlayer.getSource().getFeatures();
      let config = null;
      // if (targetlayer.values_.selectedStyle) {
      //   config = targetlayer.values_.selectedStyle;
      // }
      let feature = target.feature;
      let result = this.queryFeatures(features, feature, config);
      if (callback) {
        callback(result,extent);
      }
    });
  }
  areaGeometry(wkt) {
    let geometry = this.format.readGeometry(wkt);
    let geotype = geometry.getType().toUpperCase();
    let coordinates = geometry.getCoordinates();
    let feature = null;
    if (geotype == 'POINT') {
      feature = new turfpoint(coordinates);
    } else if (geotype == 'LINESTRING') {
      feature = new turflinestring(coordinates);
    } else if (geotype == 'MULTILINESTRING') {
      feature = new turfmultilinestring(coordinates);
    } else if (geotype == 'POLYGON') {
      feature = new turfpolygon(coordinates);
    } else if (geotype == 'MULTIPOLYGON') {
      feature = new turfmultipolygon(coordinates);
    }
    let areaed = turfarea(feature);
    return areaed;
  }
  queryFeatures(features, feature, config) {
    let result = [];
    let geometry = null;
    if (feature.getGeometry().getType() == 'Circle') {
      geometry = turfpolygon(this.createCircle(feature));
    } else {
      geometry = turfpolygon(feature.getGeometry().getCoordinates());
    }
    features.forEach(item => {
      let target = this.createTurfGeom(item);
      if (booleanIntersects(geometry, target)) {
        let f = new Feature(item.getGeometry());
        let p = item.getProperties();
        // f.setProperties(p);
        // this.map.createHighStyle(config, f);
        // this.layer.getSource().addFeature(f);
        delete p.geometry;
        if (JSON.stringify(p) != "{}") {
          result.push(p);
        }
      }
    })
    return result;
  }
  createTurfGeom(feature) {
    let geotype = feature.getGeometry().getType().toUpperCase();
    let geometry = null;
    if (geotype == 'POLYGON') {
      geometry = turfpolygon(feature.getGeometry().getCoordinates());
    } else if (geotype == 'MULTIPOLYGON') {
      geometry = turfmultipolygon(feature.getGeometry().getCoordinates());
    } else if (geotype == 'LINESTRING') {
      geometry = turflinestring(feature.getGeometry().getCoordinates());
    } else if (geotype == 'MULTILINESTRING') {
      geometry = turfmultilinestring(feature.getGeometry().getCoordinates());
    } else {
      geometry = turfpoint(feature.getGeometry().getCoordinates());
    }
    return geometry;
  }

  createCircle(feature) {
    let center = olProj.transform(feature.getGeometry().getCenter(), 'EPSG:3857', 'EPSG:4326');
    let radius = this.calcGircleRadius(feature.getGeometry());

    let circle = turfcircle(center, radius, {
      steps: 360,
      units: 'meters'
    });
    let coordinates = circle.geometry.coordinates;

    let points = [];
    for (let i = 0; i < coordinates[0].length; i++) {
      points.push(olProj.transform(coordinates[0][i], 'EPSG:4326', 'EPSG:3857'));
    }
    return [points];
  }
  calcGircleRadius(circle) {
    let from_point = toWgs84(turfpoint(circle.getCenter()));
    let to_point = toWgs84(turfpoint(circle.getLastCoordinate()));
    let radius = turfdistance(from_point, to_point, {
      units: 'meters'
    });
    return radius;
  }
  clearFilter() {
    if (this.draw) {
      this.map.removeInteraction(this.draw);
      this.draw = null;
    }
    if (this.layer) {
      this.layer.getSource().clear();
    }
    // if(this.map.interaction){
    //   this.map.interaction.click.setActive(true);
    // }
    // this.map.fixedMap(true);
  }
}
export default cuiteFilter;
